home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 8 code / AUX Hybrid Apps / AUX System Calls / src / forknpipe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-09  |  4.0 KB  |  185 lines  |  [TEXT/tefi]

  1. #include <LibAUX.h>
  2. #include </:usr:include:signal.h>
  3. #include </:usr:include:errno.h>
  4. #include </:usr:include:fcntl.h>
  5. #include <Memory.h>
  6. #include <Stdio.h>
  7. #include <String.h>
  8. #include <Events.h>
  9.  
  10. #define STACKSIZE    2048
  11.  
  12.  
  13. Handle auxfork_pipe(toparent,tochild,childtask,childargs)
  14.     int toparent,tochild,(*childtask)(),*childargs;
  15. {
  16.     Handle global_handle;
  17.     int pid,flags,parent_pipe[2],child_pipe[2],**fake=(&toparent)+4;
  18.     char *childstack;
  19.     struct childinfo *globals;
  20.     
  21.     /* Make sure A/UX is running */
  22.  
  23.     if (!AUXisRunning()) return(NULL);
  24.  
  25.     /* allocate global area */
  26.  
  27.     global_handle = NewHandle(sizeof(struct childinfo));
  28.     globals = (struct childinfo *)*global_handle;
  29.     
  30.     /* allocate temporary stack */
  31.  
  32.     globals->childstack = childstack = NewPtr(STACKSIZE);
  33.     
  34.     /* create pipes */
  35.  
  36.     if ( (toparent && (auxpipe(parent_pipe) == -1)) ||
  37.          (tochild  && (auxpipe(child_pipe)  == -1)) ) {
  38.         DisposPtr(childstack);
  39.         DisposHandle(global_handle);
  40.         return(NULL);
  41.     };
  42.     
  43.     /* setup signals */
  44.             
  45.     globals->cstat = auxsignal(SIGCLD, SIG_DFL);
  46.     globals->istat = auxsignal(SIGINT, SIG_IGN);
  47.     globals->qstat = auxsignal(SIGQUIT, SIG_IGN);
  48.             
  49.     /* fork it off (I becomes we) */
  50.  
  51.     if((pid = auxfork(childstack+STACKSIZE,fake)) == 0) {
  52.  
  53.         /* this is the child process */
  54.         
  55.         /* create pipe from child to parent */
  56.  
  57.         if ( toparent ) {
  58.             (void) auxclose(1);
  59.             (void) auxdup(parent_pipe[1]);
  60.             (void) auxclose(2);
  61.             (void) auxdup(parent_pipe[1]);
  62.             (void) auxclose(parent_pipe[0]);
  63.             (void) auxclose(parent_pipe[1]);
  64.         }
  65.         else {
  66.             (void) auxclose(1);
  67.             (void) auxclose(2);
  68.         };
  69.  
  70.         /* create pipe from parent to child */
  71.  
  72.         if ( tochild ) {
  73.             (void) auxclose(0);
  74.             (void) auxdup(child_pipe[0]);
  75.             (void) auxclose(child_pipe[0]);
  76.             (void) auxclose(child_pipe[1]);
  77.         }
  78.         else (void) auxclose(0);
  79.  
  80.         /* invoke child process now */
  81.         
  82.         (void) childtask(childargs);
  83.     }
  84.     else {
  85.     
  86.         /* this is the parent */
  87.  
  88.         /* check if fork failed */
  89.  
  90.         if (pid < 0) {
  91.         
  92.             if ( toparent ) {
  93.                 (void)auxclose(parent_pipe[0]);
  94.                 (void)auxclose(parent_pipe[1]);
  95.             };
  96.             if ( tochild ) {
  97.                 (void)auxclose(child_pipe[0]);
  98.                 (void)auxclose(child_pipe[1]);
  99.             };
  100.             (void) auxsignal(SIGCLD, globals->cstat);
  101.             (void) auxsignal(SIGINT, globals->istat);
  102.             (void) auxsignal(SIGQUIT, globals->qstat);
  103.             DisposPtr(childstack);
  104.             DisposHandle(global_handle);    
  105.     
  106.             return(NULL);
  107.         }
  108.         else {
  109.         
  110.             /* fork succeeded */
  111.  
  112.             globals->pid = pid;
  113.             globals->toparent =  toparent ? parent_pipe[0] : 0;
  114.             globals->tochild =     tochild  ? child_pipe[1]  : 0;
  115.             
  116.             /* close unneeded pipes and set flags on toparent pipe */
  117.             
  118.             if ( toparent ) {
  119.                 flags = auxfcntl(parent_pipe[0],F_GETFL,0);
  120.                 (void) auxfcntl(parent_pipe[0],F_SETFL,flags | O_NDELAY);
  121.                 (void)auxclose(parent_pipe[1]);
  122.             };
  123.             if ( tochild )  (void)auxclose(child_pipe[0]);
  124.             
  125.             return(global_handle);
  126.         }
  127.     }
  128. }
  129.  
  130.  
  131. int auxcleanup_fork_pipe(global_handle)
  132.     Handle global_handle;
  133. {
  134.     int status,n,toparent,tochild;
  135.     struct childinfo *globals;
  136.     
  137.     globals = (struct childinfo *)*global_handle;
  138.     
  139.     /* wait for child to terminate */
  140.     
  141.     for ( status=n=0; n!=globals->pid; n=auxwait(&status) ) 
  142.         if ( n<0 && GetAUXErrno()!=EINTR ) break;
  143.     
  144.     /* close open pipes */
  145.     
  146.     if ( (toparent=globals->toparent) ) auxclose(toparent);
  147.     if ( (tochild= globals->tochild)  ) auxclose(tochild);
  148.             
  149.     /* restore signal handling */
  150.     
  151.     (void) auxsignal(SIGCLD, globals->cstat);
  152.     (void) auxsignal(SIGINT, globals->istat);
  153.     (void) auxsignal(SIGQUIT, globals->qstat);
  154.     
  155.     /* dispose of temporary stack and global handle */
  156.     
  157.     DisposPtr(globals->childstack);
  158.     DisposHandle(global_handle);
  159.     
  160.     return(status);
  161. }
  162.  
  163. char *auxfgets(s,n,file,timeout)
  164.     char *s;
  165.     int n,file,timeout;
  166. {
  167.     int i;
  168.     EventRecord    theEvent;
  169.     short mask=everyEvent;
  170.     char *cp=s,*ep=s+n-1;
  171.  
  172.     for ( i=0; (i<timeout) || (timeout==0); i++ ) {
  173.         while ( cp<ep && (auxread(file,cp,1) == 1) )
  174.             if ( *cp == '\r' ) {
  175.                 *cp++ = '\n';
  176.                 i = timeout;
  177.                 break;
  178.             }
  179.             else cp++;
  180.         *cp = '\0';
  181.         (void) EventAvail(mask, &theEvent);
  182.     };
  183.     return(cp>s ? s : NULL);
  184. }
  185.